/******************************************************************************

 @file data_sender.c

 @brief Data Sender Module for TI 15.4-Stack Sensor Example

 *****************************************************************************/

#include "data_sender.h"
#include "smsgs.h"
#include "ssf.h"
#include "sensor.h"
#include "util_timer.h"
#include <ti/display/Display.h>
#include <string.h>
#include "mac_util.h"
#include "api_mac.h"

/******************************************************************************
 Global variables
 *****************************************************************************/
static ClockP_Struct sensorSendClkStruct;
static ClockP_Handle sensorSendClkHandle;

extern Display_Handle display;
extern uint16_t Sensor_events;
extern bool Sensor_sendMsg(Smsgs_cmdIds_t type, ApiMac_sAddr_t *pDstAddr,
                    bool rxOnIdle, uint16_t len, uint8_t *pData);

/******************************************************************************
 Local function prototypes
 *****************************************************************************/
static void processSensorSendTimeoutCallback(uintptr_t a0);

/******************************************************************************
 Public Functions
 *****************************************************************************/
#if 0
/*!
 * @brief       Initialize the sensor send timeout clock.
 */
void DataSender_initializeSensorSendTimeoutClock(void)
{
    /* Initialize the timers needed for this application */
    sensorSendClkHandle = UtilTimer_construct(&sensorSendClkStruct,
                                        processSensorSendTimeoutCallback,
                                        10,
                                        0,
                                        false,
                                        0);
}

/*!
 * @brief       Set the sensor send timeout clock.
 */
void DataSender_setSensorSendTimeoutClock(uint32_t sensorSendTimeout)
{
    /* Stop the Reading timer */
    if(UtilTimer_isActive(&sensorSendClkStruct) == true)
    {
        UtilTimer_stop(&sensorSendClkStruct);
    }

    /* Setup timer */
    if ( sensorSendTimeout )
    {
        UtilTimer_setTimeout(sensorSendClkHandle, sensorSendTimeout);
        UtilTimer_start(&sensorSendClkStruct);
    }
}

/*!
 * @brief       Process sensor send timeout callback.
 */
static void processSensorSendTimeoutCallback(uintptr_t a0)
{
    (void)a0; /* Parameter is not used */

    // 注意：这里需要外部设置事件，因为Sensor_events是外部变量
    Util_setEvent(&Sensor_events, SENSOR_READING_TIMEOUT_EVT);
    /* Wake up the application thread when it waits for clock event */
    Ssf_PostAppSem();
}
#endif

/*!
 * @brief       Build and send sensor data message.
 */
bool DataSender_sendSensorMessage(ApiMac_sAddr_t *pDstAddr, Smsgs_sensorMsg_t *pMsg)
{
    bool ret = false;
    uint8_t *pMsgBuf;
    uint16_t len = SMSGS_BASIC_SENSOR_LEN;
    if(pMsg->frameControl & Smsgs_dataFields_msgStats)
    {
        len += sizeof(Smsgs_msgStatsField_t);
    }
    if(pMsg->frameControl & Smsgs_dataFields_configSettings)
    {
        len += sizeof(Smsgs_configSettingsField_t);
    }
    if(pMsg->frameControl & Smsgs_dataFields_accelSingleAxisSensor)
    {
        len += sizeof(Smsgs_vibrateSensorField_t);
    }
    if(pMsg->frameControl & Smsgs_dataFields_accelThreeAxisSensor)
    {
        len += sizeof(Smsgs_vibrateSensorField_t);
    }
   /* if(pMsg->frameControl & Smsgs_dataFields_tempAndBattery)
    {
        len += sizeof(Smsgs_vibrateTemplateBat_t);
    }*/
    if(pMsg->frameControl & Smsgs_dataFields_samplingConfig)
    {
        len += sizeof(Smsgs_vibrateSampleConfig_t);
    }
    if(pMsg->frameControl & Smsgs_dataFields_channelConfig)
    {
        len += sizeof(Smsgs_vibrateChannelConfig_t) * SENSOR_CHANNEL_NUM; // 假设SENSOR_CHANNEL_NUM为3
    }
    if(pMsg->frameControl & Smsgs_dataFields_channelTempConfig)
    {
        len += sizeof(Smsgs_vibrateChannelTempConfig_t); // 假设SENSOR_CHANNEL_NUM为3
    }
    pMsgBuf = (uint8_t *)Ssf_malloc(len);
    if(pMsgBuf)
    {
        uint8_t *pBuf = pMsgBuf;

        *pBuf++ = (uint8_t)Smsgs_cmdIds_sensorData;

        pBuf  = Util_bufferUint16(pBuf,pMsg->frameControl);
        if(pMsg->frameControl & Smsgs_dataFields_msgStats)
        {
            pBuf = Util_bufferUint16(pBuf, pMsg->msgStats.joinAttempts);
            pBuf = Util_bufferUint16(pBuf, pMsg->msgStats.joinFails);
            pBuf = Util_bufferUint16(pBuf, pMsg->msgStats.msgsAttempted);
            pBuf = Util_bufferUint16(pBuf, pMsg->msgStats.msgsSent);
            pBuf = Util_bufferUint16(pBuf, pMsg->msgStats.trackingRequests);
            pBuf = Util_bufferUint16(pBuf,
                                     pMsg->msgStats.trackingResponseAttempts);
            pBuf = Util_bufferUint16(pBuf,
                                     pMsg->msgStats.trackingResponseSent);
            pBuf = Util_bufferUint16(pBuf, pMsg->msgStats.configRequests);
            pBuf = Util_bufferUint16(pBuf,
                                     pMsg->msgStats.configResponseAttempts);
            pBuf = Util_bufferUint16(pBuf,
                                     pMsg->msgStats.configResponseSent);
            pBuf = Util_bufferUint16(pBuf,
                                     pMsg->msgStats.channelAccessFailures);
            pBuf = Util_bufferUint16(pBuf, pMsg->msgStats.macAckFailures);
            pBuf = Util_bufferUint16(pBuf,
                                     pMsg->msgStats.otherDataRequestFailures);
            pBuf = Util_bufferUint16(pBuf, pMsg->msgStats.syncLossIndications);
            pBuf = Util_bufferUint16(pBuf, pMsg->msgStats.rxDecryptFailures);
            pBuf = Util_bufferUint16(pBuf,  pMsg->msgStats.txEncryptFailures);
            // 注意：这里需要外部提供Ssf_resetCount和Ssf_resetReseason
            // pBuf = Util_bufferUint16(pBuf, Ssf_resetCount);
            // pBuf = Util_bufferUint16(pBuf,  Ssf_resetReseason);
            pBuf = Util_bufferUint16(pBuf, pMsg->msgStats.joinTime);
            pBuf = Util_bufferUint16(pBuf, pMsg->msgStats.interimDelay);
            pBuf = Util_bufferUint16(pBuf, pMsg->msgStats.numBroadcastMsgRcvd);
            pBuf = Util_bufferUint16(pBuf,  pMsg->msgStats.numBroadcastMsglost);
            pBuf = Util_bufferUint16(pBuf,  pMsg->msgStats.avgE2EDelay);
            pBuf = Util_bufferUint16(pBuf,  pMsg->msgStats.worstCaseE2EDelay);
        }
        if(pMsg->frameControl & Smsgs_dataFields_configSettings)
        {
            pBuf = Util_bufferUint32(pBuf,
                                     pMsg->configSettings.reportingInterval);
            pBuf = Util_bufferUint32(pBuf,
                                     pMsg->configSettings.pollingInterval);

        }
        if(pMsg->frameControl & Smsgs_dataFields_accelSingleAxisSensor)
        {
            memcpy(pBuf, &pMsg->vibrateSensor, sizeof(Smsgs_vibrateSensorField_t));
            pBuf += sizeof(Smsgs_vibrateSensorField_t);
        }
        if(pMsg->frameControl & Smsgs_dataFields_accelThreeAxisSensor)
        {
            memcpy(pBuf, &pMsg->vibrateSensor, sizeof(Smsgs_vibrateSensorField_t));
            pBuf += sizeof(Smsgs_vibrateSensorField_t);
        }
       /* if(pMsg->frameControl & Smsgs_dataFields_tempAndBattery)
        {
            memcpy(pBuf, &pMsg->vibrateTemplateBat, sizeof(Smsgs_vibrateTemplateBat_t));
            pBuf += sizeof(Smsgs_vibrateTemplateBat_t);
        }*/
        if(pMsg->frameControl & Smsgs_dataFields_samplingConfig)
        {
            memcpy(pBuf, &pMsg->vibrateSampleConfig, sizeof(Smsgs_vibrateSampleConfig_t));
            pBuf += sizeof(Smsgs_vibrateSampleConfig_t);
        }
        if(pMsg->frameControl & Smsgs_dataFields_channelConfig)
        {
            memcpy(pBuf, &pMsg->vibrateChannelConfig, sizeof(Smsgs_vibrateChannelConfig_t) * 3);
            pBuf += sizeof(Smsgs_vibrateChannelConfig_t) * 3;
        }
        if(pMsg->frameControl & Smsgs_dataFields_channelTempConfig)
        {
            memcpy(pBuf, &pMsg->vibrateChannelTempConfig, sizeof(Smsgs_vibrateChannelTempConfig_t) * SENSOR_TEMPALTE_NUM);
            pBuf += sizeof(Smsgs_vibrateChannelTempConfig_t) * SENSOR_TEMPALTE_NUM;
        }
        
        ret = Sensor_sendMsg(Smsgs_cmdIds_sensorData, pDstAddr, true, len, pMsgBuf);

        Ssf_free(pMsgBuf);
    }

    return (ret);
}

/*!
 * @brief       Build and send config response message.
 */
bool DataSender_sendConfigRsp(ApiMac_sAddr_t *pDstAddr, Smsgs_configRspMsg_t *pMsg)
{
    uint8_t msgBuf[SMSGS_CONFIG_RESPONSE_MSG_LENGTH];
    uint8_t *pBuf = msgBuf;

    *pBuf++ = (uint8_t) Smsgs_cmdIds_configRsp;
    pBuf = Util_bufferUint16(pBuf, pMsg->status);
    pBuf = Util_bufferUint16(pBuf, pMsg->frameControl);
    pBuf = Util_bufferUint32(pBuf, pMsg->reportingInterval);
    pBuf = Util_bufferUint32(pBuf, pMsg->pollingInterval);

    return (Sensor_sendMsg(Smsgs_cmdIds_configRsp, pDstAddr, true,
                    SMSGS_CONFIG_RESPONSE_MSG_LENGTH, msgBuf));
}

/*!
 * @brief       Send LED identify request to collector.
 */
void DataSender_sendIdentifyLedRequest(ApiMac_sAddr_t *pDstAddr)
{
    uint8_t cmdBytes[SMSGS_INDENTIFY_LED_REQUEST_MSG_LEN];

    /* send the response message directly */
    cmdBytes[0] = (uint8_t) Smsgs_cmdIds_IdentifyLedReq;
    cmdBytes[1] = (uint8_t) 1; // IDENTIFY_LED_TIME
    Sensor_sendMsg(Smsgs_cmdIds_IdentifyLedReq,
            pDstAddr, true,
            SMSGS_INDENTIFY_LED_REQUEST_MSG_LEN,
            cmdBytes);
}

/*!
 * @brief       Send device type response.
 */
void DataSender_sendDeviceTypeResponse(ApiMac_sAddr_t *pDstAddr)
{
    uint8_t cmdBytes[SMSGS_DEVICE_TYPE_RESPONSE_MSG_LEN];

    /* send the response message directly */
    cmdBytes[0] = (uint8_t) Smsgs_cmdIds_DeviceTypeRsp;
    cmdBytes[1] = 0; // DeviceFamily_ID
    cmdBytes[2] = 0; // DeviceType_ID

    Sensor_sendMsg(Smsgs_cmdIds_DeviceTypeRsp,
            pDstAddr, true,
            SMSGS_DEVICE_TYPE_RESPONSE_MSG_LEN, cmdBytes);
}

/*!
 * @brief       Send reboot response.
 */
void DataSender_sendRebootRsp(ApiMac_sAddr_t *pDstAddr, uint8_t status)
{
    uint8_t cmdBytes[SMSGS_REBOOT_RSP_MSG_LEN];

    cmdBytes[0] = (uint8_t)Smsgs_cmdIds_RebootRsp;
    cmdBytes[1] = status;

    /* Best-effort send of reboot response; ignore return value */
    (void)Sensor_sendMsg(Smsgs_cmdIds_RebootRsp,
                         pDstAddr,
                         true,
                         SMSGS_REBOOT_RSP_MSG_LEN,
                         cmdBytes);
}